package main

import (
	"encoding/json"
	"fmt"
	"os"
	"io"
	"io/ioutil"
	"net"
	"log"
	"flag"
	"os/signal"
	"syscall"
	"time"
	"strings"
	"strconv"
    "archive/zip"
    //"bufio"
)

var (
    config Config
    ch_trans chan bool
    //is_start_recvChan = make(chan bool, 1)
    //is_end_recvChan = make(chan bool, 1)
)

// Config 配置
type Config struct {
	Client *ClientConfig `json:"client"`
    Server *ServerConfig `json:"server"`
}

// ClientConfig 客户端配置
type ClientConfig struct {
	Name       string   `json:"name"`        // 名称
	Addr       string   `json:"addr"`        //服务端地址
}

// ServerConfig 服务端配置
type ServerConfig struct {
	Name       string   `json:"name"`        // 名称
	Port       int      `json:"port"`        //服务端口
    Sdir       string   `json:"s_dir"`            //服务器文件夹
    Cdir       string   `json:"c_dir"`            //临时接收文件夹
}


//压缩文件
//src 可以是不同dir下的文件或者文件夹
//dest 压缩文件存放地址
func Compress(src string, dest string) error {
	f, err := os.Open(src)
	if err != nil {
		return err
	}
	files := []*os.File{f}
	d, _ := os.Create(dest)
	defer d.Close()
	w := zip.NewWriter(d)
	defer w.Close()
	for _, file := range files {
		err := compress(file, "", w)
		if err != nil {
			return err
		}
	}
	return nil
}
 
func compress(file *os.File, prefix string, zw *zip.Writer) error {
	info, err := file.Stat()
	if err != nil {
		return err
	}
	if info.IsDir() {
		prefix = prefix + "/" + info.Name()
		fileInfos, err := file.Readdir(-1)
		if err != nil {
			return err
		}
		// 增加对空目录的判断
		if len(fileInfos) <= 0 {
			header, err := zip.FileInfoHeader(info)
			header.Name = prefix
			if err != nil {
				fmt.Println("error is:"+err.Error())
				return err
			}
			_, err = zw.CreateHeader(header)
			if err != nil {
				fmt.Println("create error is:"+err.Error())
				return err
			}
			file.Close()
		}
		for _, fi := range fileInfos {
			f, err := os.Open(file.Name() + "/" + fi.Name())
			if err != nil {
				return err
			}
			err = compress(f, prefix, zw)
			if err != nil {
				return err
			}
		}
	} else {
		header, err := zip.FileInfoHeader(info)
		header.Name = prefix + "/" + header.Name
		if err != nil {
			return err
		}
		writer, err := zw.CreateHeader(header)
		if err != nil {
			return err
		}
		_, err = io.Copy(writer, file)
		file.Close()
		if err != nil {
			return err
		}
	}
	return nil
}
 
//解压
func DeCompress(zipFile, dest string) error {
	reader, err := zip.OpenReader(zipFile)
	if err != nil {
		return err
	}
	defer reader.Close()
	for _, file := range reader.File {
		rc, err := file.Open()
		if err != nil {
			return err
		}
		defer rc.Close()
		filename := dest + file.Name
		err = os.MkdirAll(getDir(filename), 0755)
		if err != nil {
			return err
		}
		w, err := os.Create(filename)
		if err != nil {
			return err
		}
		defer w.Close()
		_, err = io.Copy(w, rc)
		if err != nil {
			return err
		}
		w.Close()
		rc.Close()
	}
	return nil
}
 
func getDir(path string) string {
	return subString(path, 0, strings.LastIndex(path, "/"))
}
 
func subString(str string, start, end int) string {
	rs := []rune(str)
	length := len(rs)
 
	if start < 0 || start > length {
		panic("start is wrong")
	}
 
	if end < start || end > length {
		panic("end is wrong")
	}
 
	return string(rs[start:end])
}

/* 以下为客户端程序 */
func Sendgetallend(conn net.Conn){
    _,err := conn.Write([]byte("getallend"))
    if err!=nil{
        fmt.Println(err)
        return
    }
}

//全双工的sendDir, 实现在一个connection中传输整个文件夹
func SendDir_compress(path string, conn net.Conn){
    //先处理path 如果path=1.txt 就取1.1.1
    pathFile := "tmp_" + time.Now().Format("20060102") + "_" + strconv.FormatInt(time.Now().Unix(), 10) + ".zip"
    Compress(path, pathFile)
    
    info, err:=os.Stat(pathFile)
    if err!=nil{
        fmt.Println(err)
        return
    }
    log.Println("文件名: ", info.Name())
    log.Println("文件大小: ", info.Size() / 1024 , "KB")
    
    
    _,err=conn.Write([]byte(info.Name()))
    if err!=nil{
        fmt.Println(err)
        return
    }
    
    var n int
    buf := make([]byte, 1024)
    n,err=conn.Read(buf)
    if err!=nil{
        fmt.Println(err)
        return
    }
    
    if "ok" == string(buf[:n]) {
        //send file
        log.Println("发送中...")
        SendFile(pathFile, conn)
    }
    

}

//全双工的sendDir, 实现在一个connection中传输整个文件夹
func SendDir2(path string, conn net.Conn){
    fs,_:= ioutil.ReadDir(path)
    for _,file:=range fs{
        if file.IsDir(){  //如果是文件夹, 继续往下搜
            fmt.Println(path+file.Name())
            SendDir2(path+file.Name()+"/", conn)
            //getFileList(path+file.Name()+"/")
        }else{
            fmt.Println(path+file.Name())
            pathFile := path+file.Name()
            
            //todo
            
            info, err:=os.Stat(pathFile)
            if err!=nil{
                fmt.Println(err)
                continue
            }
            log.Println("文件名: ", info.Name())
            log.Println("文件大小: ", info.Size() / 1024 , "KB")
            
            
            _,err=conn.Write([]byte(info.Name()))
            if err!=nil{
                fmt.Println(err)
                continue
            }
            
            var n int
            buf := make([]byte, 1024)
            n,err=conn.Read(buf)
            if err!=nil{
                fmt.Println(err)
                continue
            }
            
            if "ok" == string(buf[:n]) {
                //send file
                log.Println("发送中...")
                SendFile(pathFile, conn)
            }

        }
    }

}

// 发送文件夹
func SendDir(path string){
    
    fs,_:= ioutil.ReadDir(path)
    for _,file:=range fs{
        if file.IsDir(){  //如果是文件夹, 继续往下搜
            fmt.Println(path+file.Name())
            SendDir(path+file.Name()+"/")
            //getFileList(path+file.Name()+"/")
        }else{
            fmt.Println(path+file.Name())
            pathFile := path+file.Name()
            
            //todo
            
            info, err:=os.Stat(pathFile)
            if err!=nil{
                fmt.Println(err)
                continue
            }
            log.Println("文件名: ", info.Name())
            log.Println("文件大小: ", info.Size() / 1024 , "KB")
            
            
            conn, err:=net.Dial("tcp", config.Client.Addr)
            if err!=nil{
                fmt.Println(err)
                continue
            }
            
            log.Println("连接服务器成功!")
            defer conn.Close()
            
            
            _,err=conn.Write([]byte(info.Name()))
            if err!=nil{
                fmt.Println(err)
                continue
            }
            
            var n int
            buf := make([]byte, 1024)
            n,err=conn.Read(buf)
            if err!=nil{
                fmt.Println(err)
                continue
            }
            
            if "ok" == string(buf[:n]) {
                //send file
                log.Println("发送中...")
                SendFile(pathFile, conn)
            }

        }
    }

    

}

// 遍历文件夹
func getFileList(path string) string {
    var re string
    fs,_:= ioutil.ReadDir(path)
    for _,file:=range fs{
        if file.IsDir(){  //如果是文件夹, 继续往下搜
            fmt.Println(path+file.Name())
            getFileList(path+file.Name()+"/")
        }else{
            fmt.Println(path+file.Name())
            re = re + "\n" + path+file.Name() + " " + strconv.FormatInt(file.Size() / 1024, 10) + "KB"
        }
    }
    return re
}

// 发送文件
func SendFile(path string, conn net.Conn){
    f,err:=os.Open(path)
    if err!=nil{
        fmt.Println(err)
        return
    }
    defer f.Close()

    /* 新增 续传功能 */
    srcFile := path 
    destFile := srcFile[strings.LastIndex(srcFile, "/")+1:]  //从D:/1.txt里取1.txt
    tempFile := destFile + "temp.txt"  //1.txt => 1.txttemp.txt
    fmt.Println("生成临时文件: ", tempFile)
    file3, err := os.OpenFile(tempFile, os.O_CREATE | os.O_RDWR, os.ModePerm)
    if err != nil {
        return
    }

    //step1
    file3.Seek(0, io.SeekStart)
    bs := make([]byte, 100, 100)
    n1, err:=file3.Read(bs)
    //HandleErr(err)
    countStr:=string(bs[:n1])
    count, err:=strconv.ParseInt(countStr, 10, 64)
    //HandleErr(err)
    fmt.Println("count:", count)
    
    //step2
    f.Seek(count, io.SeekStart)  //这一步定位到上次断开的地方
    n :=-1
    total:=int(count)
    /* 新增 end*/
    
    buf := make([]byte, 1024*4)
    for {
        select {
        case <- ch_trans:  //如果接收到暂时的信号
            log.Println("暂停发送")
            return
        default:
            n,err=f.Read(buf)
            if err!=nil{
                if err == io.EOF {
                    conn.Close()
                    log.Println("发送完毕send over")
    
                    file3.Close()  //新增
                    os.Remove(tempFile)  //新增
    
                }else{
                    fmt.Println(err)
                }
                return
            }
            
            conn.Write(buf[:n])
    
            /* 新增 */
            total+=n
            file3.Seek(0, io.SeekStart)
            file3.WriteString(strconv.Itoa(total))
            /* 新增 end */
        }
    }
}

// 判断所给路径文件/文件夹是否存在 
func Exists(path string) bool {  
    _, err := os.Stat(path)    //os.Stat获取文件信息  
    if err != nil {  
        if os.IsExist(err) {  
            return true  
        }  
        return false  
    }  
    return true  
}  
  
// 判断所给路径是否为文件夹  
func IsDir(path string) bool {  
    s, err := os.Stat(path)  
    if err != nil {  
        return false  
    }  
    return s.IsDir()  
}  
  
// 判断所给路径是否为文件  
func IsFile(path string) bool {  
    return !IsDir(path)  
}

func send_conn(command string){
        conn, err:=net.Dial("tcp", config.Client.Addr)
        if err!=nil{
            fmt.Println(err)
            return
        }
        
        log.Println("连接服务器成功!")
        
        defer conn.Close()
        
        if command == "get" {  //拿到目录列表
            _,err=conn.Write([]byte(command))
            if err!=nil{
                fmt.Println(err)
                return
            }
            
            //如果是get 仅仅返回数据列表
            var n int
            var list string
            buf := make([]byte, 1024)
            for {
                n,err=conn.Read(buf)
                if err != nil{
                    if err == io.EOF {
                        //log.Println("文件夹为空...")
                        
                    }else{
                        log.Println(err)
                        
                    }
                    break
                }
                list = list + string(buf[:n])
            }


            log.Println(list)  
            
        } else if len(command) > 4 && command[:4] == "get|" {  //发服务器发送get文件请求

            _,err=conn.Write([]byte(command))
            if err!=nil{
                fmt.Println(err)
                return
            }
            
            
            log.Println("正在接收数据...")
            
            
            buf := make([]byte, 1024)
            
            for {
                n, err := conn.Read(buf) //读取对方发送的文件名
                if err != nil{
                    if err == io.EOF {  //如果接收到文件末
                        //log.Println("接收到EOF")
                        break
                    } else {
                        log.Println("接收到错误")
                        fmt.Println(err)
                        return
                    }
                    
                    
                }
                fileName := string(buf[:n])
                log.Println("接收到的信息: ", fileName)
                if "nofile" == fileName {
                    log.Println("文件/文件夹不存在")
                    return
                }


                
                log.Println("向客户端发送ok")
                conn.Write([]byte("ok"))
                
                log.Println("接收中...")
                
                /*      以下处理接收文件    */
                RecvFile(fileName, conn)
                /*       end               */
                
                log.Println(fileName, "接收完毕")

            }
            
        } else if len(command) > 4 && command[:4] == "del|" {  //发服务器发送del

            Client_Action(command, conn)
            
        } else if command == "getall" {  //传输整个目录
            
            _,err=conn.Write([]byte(command))
            if err!=nil{
                fmt.Println(err)
                return
            }
            
            
            log.Println("正在接收数据...")
            
            
            buf := make([]byte, 1024)
            
            for {
                n, err := conn.Read(buf) //读取对方发送的文件名
                if err != nil{
                    if err == io.EOF {  //如果接收到文件末
                        //log.Println("接收到EOF")
                        break
                    } else {
                        log.Println("接收到错误")
                        fmt.Println(err)
                        return
                    }
                    
                    
                }
                fileName := string(buf[:n])
                log.Println("接收到的信息: ", fileName)
                
                
                log.Println("向客户端发送ok")
                conn.Write([]byte("ok"))
                
                log.Println("接收中...")
                
                
                /*      以下处理接收文件    */
                RecvFile(fileName, conn)
                /*       end               */
                
                log.Println(fileName, "接收完毕3...开始解压缩...")
                
                if err1 := DeCompress(config.Server.Cdir + fileName, config.Server.Cdir); err1 != nil {
                    log.Println("解压缩错误...")
                    log.Println(err1)
                } else {
                    log.Println("解压成功....")
                }
                
                
            }

        }


//                 if "ok" == string(buf[:n]) {
//                     //send file
//                     log.Println("发送中...")
//                     //SendFile(path, conn)
//                 }
        
        log.Println("断开连接")
}

func Client_Action(command string, conn net.Conn) error {
    _,err := conn.Write([]byte(command))
    if err!=nil{
        fmt.Println(err)
        return err
    }
    log.Println("正在接收数据...")
    buf := make([]byte, 1024)
    for {
        n, err := conn.Read(buf) //读取对方发送的结果
        if err != nil{
            if err == io.EOF {  //如果接收到文件末
                //log.Println("接收到EOF")
                break
            } else {
                log.Println("接收到错误")
                fmt.Println(err)
                return err
            }
            
            
        }
        fileName := string(buf[:n])
        log.Println("接收到的信息: ", fileName)
        if "nofile" == fileName {
            log.Println("服务器端 文件/文件夹不存在")
            
            return nil
        }
        log.Println(fileName)
        
    }
    return nil
}


func client(){
    for {
            fmt.Println("请输入: ")
            var path string 
            fmt.Scan(&path)
            //b2 := bufio.NewReader(os.Stdin)
            //path, _ := b2.ReadString('\n')
            
            if path == "get" {  //如果是get命令
                log.Println("get")
                send_conn("get")
                
            } else if len(path) > 4 && path[:4] == "get|"{  //如果是要某个文件 get|1.txt
                fileName := strings.Split(path, "|")[1]
                log.Println("get|", fileName)
                send_conn("get|" + fileName)
                
            } else if len(path) > 4 && path[:4] == "del|"{  //删除某个文件
                fileName := strings.Split(path, "|")[1]
                log.Println("del|", fileName)
                send_conn("del|" + fileName)
                        
            } else if path == "getall" {  //发送getall
                
                log.Println("getall")
                send_conn("getall")
                
            } else { //如果是文件之类的
                if !Exists(path) {  //如果文件/文件夹不存在
                    log.Println("文件/文件夹不存在")
                    
                } else {
                    if IsFile(path) {
                        log.Println("发送文件...")
                        info, err:=os.Stat(path)
                        if err!=nil{
                            fmt.Println(err)
                            return
                        }
                        log.Println("文件名: ", info.Name())
                        log.Println("文件大小: ", info.Size() / 1024 / 1024, "MB")
                        
                        conn, err:=net.Dial("tcp", config.Client.Addr)
                        if err!=nil{
                            fmt.Println(err)
                            return
                        }
                        
                        log.Println("连接服务器成功!")
                        
                        defer conn.Close()
                        
                        //s_info := info.Name() + "|" + info.Size()
                        _,err=conn.Write([]byte(info.Name()))
                        if err!=nil{
                            fmt.Println(err)
                            return
                        }
                        
                        var n int
                        buf := make([]byte, 1024)
                        n,err=conn.Read(buf)
                        if err!=nil{
                            fmt.Println(err)
                            return
                        }
                        
                        if "ok" == string(buf[:n]) {
                            //send file
                            log.Println("发送中...")
                            SendFile(path, conn)
                        }
                        log.Println("断开连接")
                        
                        
                    } else if IsDir(path) {  //如果是文件夹
                        log.Println("发送文件夹...")
                        SendDir(path)
                        
                    } else {
                        
                    }
                }
            }
    }
}

/* --------------------以下为服务器功能------------------------- */


//判断文件夹是否存在  存在就返回true
func HasDir(path string) (bool, error) {
    _, _err := os.Stat(path)
    if _err == nil {
        return true, nil
    }
    if os.IsNotExist(_err) {
        return false, nil
    }
    return false, _err
}
  
//创建文件夹
func CreateDir(path string) {
    exist, err := HasDir(path)
    if err != nil {
        fmt.Printf("获取文件夹异常 -> %v\n", err)
        return
    }
    if exist {
        //fmt.Println("文件夹已存在！")
    } else {
        err := os.Mkdir(path, os.ModePerm)
        if err != nil {
            fmt.Printf("创建目录异常 -> %v\n", err)
        } else {
            fmt.Println("创建成功!")
        }
    }
}

//分割文件名  1.1.txt => 1.1  ,   txt
func handle_filename(fileName string) string {
	sfileName := strings.Split(fileName, ".") //用.进行split分割  nginx.1.23.1.rar => 
	t3 := sfileName[0] + "_" + time.Now().Format("20060102") + "_" + strconv.FormatInt(time.Now().Unix(), 10)
	var file string
	if len(sfileName) < 2 { //如果不带后辍
		file = t3
	}else if len(sfileName) == 2 {  //如果是  1.txt
		file = t3 + "." + sfileName[1]
	}else {
        file = t3 + "." + sfileName[len(sfileName)-1]
    }
    return file
}

//接收一个文件
func RecvFile(fileName string, conn net.Conn)(){

    /* handle 兼容 1.txt  1.txt|1234 两种格式 */
    var _fileName, _fileSize string
    if strings.Index(fileName, "|") == -1 {
        _fileName = fileName
        _fileSize = "0"
    }else{
        _fileName = strings.Split(fileName, "|")[0]
        _fileSize = strings.Split(fileName, "|")[1]
    }
    fileSize,_ := strconv.Atoi(_fileSize)
    /* handle end */

	//file:=handle_filename(fileName)  //改名
	file:=_fileName
	
    log.Println(file)
    log.Println(fileSize)

    CreateDir(config.Server.Cdir)  //如果有没接收文件夹就创建
    //new
    f,err:=os.Create(config.Server.Cdir + file)
    if err!=nil{
        log.Println("本地文件夹已存在, 创建文件夹失败")
        fmt.Println(err)
        return
    }
    
    buf := make([]byte, 1024*4)
    
    
    /* 新增 */
    tempFile := file + "temp.txt"
    fmt.Println("生成临时文件: ", tempFile)
    file3, err := os.OpenFile(tempFile, os.O_CREATE | os.O_RDWR, os.ModePerm)
    if err != nil {
        return
    }

    //step1
	file3.Seek(0, io.SeekStart)
	bs := make([]byte, 100, 100)
	n1, err:=file3.Read(bs)
	//HandleErr(err)
	countStr:=string(bs[:n1])
	count, err:=strconv.ParseInt(countStr, 10,64)
	//HandleErr(err)
    fmt.Println(count)
    
    //step2
	f.Seek(count, io.SeekStart)
	n :=-1
	total:=int(count)
    /* 新增 end*/

    for {
		// ReadByte(conn, func(data []byte){
		// 	//code
		// 	log.Println("start readbyte")
		// }).callback(func(){
		// 	//callbak
		// 	log.Println("end readbyte")
		// })
        
        
        
        n, err=conn.Read(buf)
        
        if err != nil{
            
            if err == io.EOF {
                log.Println(fileName, "接收完毕!")
            }else{
                log.Println(err)
            }
            f.Close()  //注意文件要关闭

            file3.Close()  //新增
            if total == fileSize {  //如果文件大小发送完毕就删除临时文件
                os.Remove(tempFile)  //新增
            }
            

            return
        }
        if n == 0 {
            fmt.Println("n==0文件接收完毕")
            f.Close()  //注意文件要关闭

            file3.Close()  //新增
            if total == fileSize {  //如果文件大小发送完毕就删除临时文件
                os.Remove(tempFile)  //新增
            }

            return
        } else {
            //fmt.Println(n, i)
        }
        
        if _, err := f.Write(buf[:n]); err != nil {
            fmt.Println(err)
            return
        }

        /* 新增 */
        total+=n
		file3.Seek(0, io.SeekStart)
		file3.WriteString(strconv.Itoa(total))
		//fmt.Println("total", total)
        /* 新增 end */
        
    }
    //fmt.Println("recv...")  //这句不会被执行
    
}

func handle(conn net.Conn){
	defer func(){
        log.Println("关闭连接...", conn.RemoteAddr().String())
        conn.Close()
    }()
	log.Println("连接进入, 开始接收...", conn.RemoteAddr().String())
    
    /*  读取文件 或 命名 */
    buf := make([]byte, 1024)
    n, err := conn.Read(buf) //读取对方发送的文件名
    if err==io.EOF{
        //fmt.Println("eof")
        return
    }
    if err!=nil{
        fmt.Println(err)
        return
    }
	fileName := string(buf[:n])
    /* 读取end */
    
    if "get" == fileName {  //接收到get命令,  向对方发送文件列表
        log.Println("接收命令get")
        tmp_str := getFileList(config.Server.Sdir)
        log.Println(tmp_str)
        log.Println("向客户端发送")
        conn.Write([]byte(tmp_str))
        log.Println("断开连接")
    } else if len(fileName) > 4 && fileName[:4] == "get|"{  //接收get|1.txt命令，向对方发送单个文件
        log.Println("接收命令", fileName)
        _file := strings.Split(fileName, "|")[1]  //1.txt
        file := config.Server.Sdir + _file   //./tmp/1.txt
        if !Exists(file) {  //如果文件不存在
            log.Println("文件/文件夹不存在")  
            log.Println("向客户端发送")            
            conn.Write([]byte("nofile"))
            log.Println("断开连接")
        } else {  //如果存在则传递 全双工
            log.Println("发送文件...")
            path := file
            info, err:=os.Stat(path)
            if err!=nil{
                fmt.Println(err)
                return
            }
            log.Println("文件名: ", info.Name())
            log.Println("文件大小: ", info.Size() / 1024 / 1024, "MB")
            
            /* 新增 */
            s_info := info.Name() + "|" + fmt.Sprintf("%d", info.Size())  //1.txt|1234
            log.Println("发送命令 ", s_info)
            //_,err=conn.Write([]byte(info.Name()))
            _,err=conn.Write([]byte(s_info))
            /* 新增 end */
            if err!=nil{
                fmt.Println(err)
                return
            }
            
            var n int
            buf := make([]byte, 1024)
            n,err=conn.Read(buf)
            if err!=nil{
                fmt.Println(err)
                return
            }
            
            if "ok" == string(buf[:n]) {
                //send file
                log.Println("发送中...")
                go listen_pause(conn)  //监听暂停信号
                SendFile(path, conn)  //调用方法
            }
            log.Println("断开连接")
        }
                        
        
    } else if len(fileName) > 4 && fileName[:4] == "del|"{  //接收del|1.txt命令
        Action_del(fileName, conn)
    } else if "getall" == fileName { //接收到getall命令, 通知client.senddir
        //is_start_recvChan <- true
        log.Println("接收命令getall")
        SendDir_compress(config.Server.Sdir, conn)  //全双工传输, 连接完毕直接return过来
        
        
        //time.Sleep(time.Second)  //等待一秒, 清空buf
        log.Println("断开连接")
        //Sendgetallend(conn)  //发送一条结束 本次连接结束
        
    } else {
        
        
        log.Println("向客户端发送ok")
        conn.Write([]byte("ok"))
        
        log.Println("接收中...")

        RecvFile(fileName, conn)
        log.Println("接收完毕2...")
        log.Println("断开连接")
                    
        
    }

}

func Action_del(fileName string, conn net.Conn)  {
    log.Println("接收命令", fileName)
    _file := strings.Split(fileName, "|")[1]  //1.txt
    file := config.Server.Sdir + _file   //./tmp/1.txt
    if !Exists(file) {  //如果文件不存在
        log.Println("文件/文件夹不存在")  
        log.Println("向客户端发送")            
        conn.Write([]byte("nofile"))
        log.Println("断开连接")
    } else {  //如果存在则del
        log.Println("删除文件")
        path := file
        info, err:=os.Stat(path)
        if err!=nil{
            fmt.Println(err)
            return
        }
        log.Println("文件名: ", info.Name())
        log.Println("文件大小: ", info.Size() / 1024 / 1024, "MB")
        
        //todo 删除文件
        err = os.Remove(file)
        if err != nil {
            log.Println(err)
            return
        }
        //end
        conn.Write([]byte("del_ok"))
        log.Println("断开连接")
    }
}

func serve(){
	log.Println("start server...", "0.0.0.0:", config.Server.Port)
    listenner, err:=net.Listen("tcp", fmt.Sprintf("0.0.0.0:%v",config.Server.Port))
    if err!=nil{
        fmt.Println(err)
        return
	}
	
	for {
		conn,err:=listenner.Accept()
		if err!=nil{
			fmt.Println(err)
			continue
		}

		go handle(conn)

	}
    //defer listenner.Close()
}

func main()  {
    
    //getFileList("./tmp")
    //return

	cfg:=flag.String("f","config.json","Config file")
    //d:=flag.String("d", "file", "file or dir")  //接收一个d参数, 判断是file 还是 dir d是一个指针一个地址, 默认是文件
    //file:=flag.String("file", "D:/CYJ/", "input file name")
	flag.Parse()
    //fmt.Println(*d)
    //return
	/*  载入 配置 */
	configBytes,err:=ioutil.ReadFile(*cfg)
	if err!=nil{
		panic(err)
	}
	
	err=json.Unmarshal(configBytes,&config)
	if err!=nil{
		panic(err)
	}

	psignal:=make(chan os.Signal,1)
	//ctrl+c -> signint, kill -9 -> signkill
    signal.Notify(psignal,syscall.SIGINT,syscall.SIGKILL)
    
    ch_trans = make(chan bool, 1)
    
    go serve()
	go client()

	<-psignal
	log.Println("Bye!")

}

//用于监听中断的conn请求
func listen_pause(conn net.Conn){
    buf := make([]byte, 1024)
    for{
        n,err:=conn.Read(buf)
        if err!=nil{
            fmt.Println(err)
            return
        }

        command := string(buf[0:n])
        log.Println("接到客户端信息:", command)
        if command == "pause" {
            ch_trans <- true
            return
        }
    }

}